#include "port.h"
#include <string.h>
#include <stdio.h>
#include "physics.h"
#include "game.h"
#include "player.h"
#include "background.h"
#include "common.h"
#include "shot.h"
#include "weapon.h"

// Timer code
#include "timer.h"
// End

// This is called ONCE!
int GameModule::init()
{
    /** Lazy non error-checking code */
    allegro_init();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED,1000,700,0,0);

    install_keyboard();
    install_mouse();
    install_timer();

    // Start timer
    timer_init();

    // Random number generator
    srand(time(0));
	
	// TODO: Much of the functions down here
	// should be "moved" (converted) into newGame(), as
	// they handle a lot of per-game setup
	
    // Make databank
    dataBank = new DataBank;
    dataBank->readData();

    // Setup world
    dataBank->init();

    // See the world /o/
    view = new ViewModule(dataBank);
    view->setup();
    
    // Local stuff
    demo = false;

    return 0;
}



void GameModule::setupGame()
{
    frameCount = 0;
	setTimer();
	deltaAvg = 0.0;
	speedTimer = 0.0;
	fpsCounter = 0;
	endTimer = 60.0;
	
	// Setup player count [this will be moved later]
	int plcount = (gameType==GAME_DEMO) ? 0 : dataBank->getconfig()->numPlayers;
	
	// Setup databank
	dataBank->newGame(plcount, gameType);

	if(gameType == GAME_DEMO) {
		curPl = NULL;
		curWeapon = NULL;
	}else {
		curPl = dataBank->getPlayer(0);
	}
	
	curPlayer = 0;
	turnStatus = TURN_PLAYER;
}

/* Called first to setup the game.
 * This is a function designed to be called
 * every time a game is prepared. It handles
 * initialization of all data and all that
 * Then run() is called subsequently.
 * If the gametype is GAME_DEMO
 * run may be called as often as desired
 * and it will continue on with the game
 */
void GameModule::newGame(GameType gt)
{
	// Clear the old
	dataBank->clear();
	
	// Set timer stuff
	// and other pre-game stuff
	gameType = gt;
	setupGame();
}

void GameModule::run()
{
    // Run main loop
    while(!(key[KEY_ESC]) || gameType==GAME_DEMO) {
        if(newFrame()) {
        	frameUpdate = true;
            // This makes for perfect timing, even with billions of particles :D
            delta = getDelta();
            updateTimer();

		        if(dataBank->getPhysicsModule()->doPhysics(delta)) {
		            dataBank->getBackground()->updateZones();
		        }

		    // Update zones ever second
	        if(frameCount % (FPS*1) == 0)
		            dataBank->getBackground()->updateZones();
			
			// Test turn status for player
			// and process turn-dependent stuff
			turnRevolve();
			
			// Test for dead players
			for(int i=0;i<dataBank->getPlayerSize(); i++) {
				if(dataBank->getPlayer(i)->getHP() <= 0) {
					dataBank->getPlayer(i)->testDead(dataBank);
				}
			}
			
			// Exit when only one player remains
			if(gameOver(gameType))
				return;
			
			if(gameType != GAME_DEMO)
		        view->paint(this);
		}else {
			frameUpdate = false;
		}
		
		if(curPl != NULL) {
            if(turnStatus == TURN_PLAYER) {
                curPl->input();
            }
            if(turnStatus == TURN_SHOT) {
                dataBank->interactShots(curPl);
            }
        }
    }

    return;
}

